home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
utils
/
clocks
/
sunclock.zoo
/
SOURCES
/
SUNCLOCK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-08
|
21KB
|
791 lines
/*
ATARI-ST clock by Joep Mathijssen
Original header:
---------------
Sun clock
Designed and implemented by John Walker in November of 1988.
Version for the Sun Workstation.
The algorithm used to calculate the position of the Sun is given in
Chapter 18 of:
"Astronomical Formulae for Calculators" by Jean Meeus, Third Edition,
Richmond: Willmann-Bell, 1985. This book can be obtained from:
Willmann-Bell
P.O. Box 35025
Richmond, VA 23235
USA
Phone: (804) 320-7016
This program was written by:
John Walker
Autodesk, Inc.
2320 Marinship Way
Sausalito, CA 94965
USA
Fax: (415) 389-9418
Voice: (415) 332-2344 Ext. 2829
Usenet: {sun,well,uunet}!acad!kelvin
or: kelvin@acad.uu.net
This program is in the public domain: "Do what thou wilt shall be the
whole of the law". I'd appreciate receiving any bug fixes and/or
enhancements, which I'll incorporate in future versions of the
program. Please leave the original attribution information intact so
that credit and blame may be properly apportioned.
Revision history:
1.0 12/21/89 Initial version.
8/24/89 Finally got around to submitting.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <assert.h>
#include <tos.h>
#include <vdi.h>
#include <aes.h>
#include "gem.h"
#include "dialog.h"
#include "scr2.h"
#include "sunclock.img" /* Icon and open window bitmaps */
#include "sunclock.h" /* .RCS-file */
/*----- Prototypes -----*/
void pw_setmode( int );
void pw_vector( void*, int, int, int, int, int, int );
void pw_b_on( void* );
void pw_b_off( void* );
void updimage( int );
void timer_proc( void );
static void cevent( void );
static long jdate( struct tm* );
static double jtime( struct tm* );
static double kepler( double, double );
static void sunpos( double, int, double*, double*, double*, double* );
static double gmst( double );
static void projillum( short*, int, int, double );
static void xspan( int, int, int );
static void moveterm( short*, int, short*, int, int, int );
OBJECT *dialog_addr;
bool bufferio;
#define abs(x) ((x) < 0 ? (-(x)) : x) /* Absolute value */
#define sgn(x) (((x) < 0) ? -1 : ((x) > 0 ? 1 : 0)) /* Extract sign */
#define dtr(x) ((x) * (PI / 180.0)) /* Degree->Radian */
#define rtd(x) ((x) / (PI / 180.0)) /* Radian->Degree */
#define fixangle(a) ((a) - 360.0 * (floor((a) / 360.0))) /* Fix angle */
#define V (void)
#define PI 3.14159265358979323846
#define TERMINC 100 /* Circle segments for terminator */
#define PROJINT (60 * 10) /* Frequency of seasonal recalculation
in seconds. */
#define OXDOTS 640 /* Open window width */
#define OYDOTS 320 /* Open window height */
/* Globals imported */
extern time_t time();
/* Local variables */
static int xdots, ydots; /* Screen size */
static char *wdname[] = { /* Week day names */
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static int onoon = -1;
static short *wtab, *wtab1, *wtabs;
static int fdate = FALSE, idir = 1, animate = FALSE;
static long lincr = 3600;
static long cctime;
/* Forward procedures */
double jtime(), gmst();
void drawterm(), sunpos(), projillum(), moveterm(), outdiff();
/* PW_MODE: GEM-version */
#define PIX_SRC 0x01
#define PIX_DST 0x02
#define PIX_NOT ~
/* Used in pw_vector. Not complete! */
void pw_setmode(pw_mode)
int pw_mode;
{
int gemmode = 1;
switch (pw_mode) {
case PIX_SRC ^ PIX_DST:
gemmode = 3;
break;
}
vswr_mode(handle, gemmode);
}
/* PW_VECTOR: draw a line using gem. Could draw directly to screen or
by a Aline for speed, but this is easier */
void pw_vector(pw, x1, y1, x2, y2, mode, color)
void *pw;
int x1, x2, y1, y2, mode, color;
{
pw_setmode(mode);
vsl_color(handle, color);
pxyarray[0] = x1;
pxyarray[1] = y1;
pxyarray[2] = x2;
pxyarray[3] = y2;
v_pline(handle,2,pxyarray);
}
/* PW_BATCH_ON/OFF: use define to avoid double define because of
8 chars limit */
#define pw_batch_on pw_b_on
void pw_b_on(pw)
void *pw;
{
Scr2Init();
Scr2Copy();
}
#define pw_batch_off pw_b_off
void pw_b_off(pw)
void *pw;
{
Scr2Swap();
Scr2Exit();
}
/* UPDIMAGE -- Update current displayed image. */
static void updimage(istimer)
int istimer;
{
int i, xl;
struct tm *ct;
char tbuf[100];
double jt, sunra, sundec, sunrv, sunlong, gt;
struct tm lt;
static int lisec = 61; /* Last iconic seconds */
static long lctime = 0; /* Last full calculation time */
static int *cpw;
if (!istimer) {
xdots = OXDOTS;
ydots = OYDOTS;
cpw = Logbase();
for (i=0 ; i < sizeof(bimg)/sizeof(int) ; i++)
cpw[i] = ~(bimg[i]);
for (; i < 16000 ; i++)
cpw[i] = 0xFFFF;
}
/* If this is a full repaint of the window, force complete
recalculation. */
if (!istimer) {
lctime = 0;
onoon = -1;
lisec = 61;
for (i = 0; i < OYDOTS; i++)
wtab1[i] = -1;
}
if (fdate) {
if (animate)
cctime += lincr;
if (cctime < 0)
cctime = 0;
} else {
V time(&cctime);
}
lt = *localtime(&cctime);
ct = gmtime(&cctime);
jt = jtime(ct);
sunpos(jt, FALSE, &sunra, &sundec, &sunrv, &sunlong);
gt = gmst(jt);
/* Projecting the illumination curve for the current seasonal
instant is costly. If we're running in real time, only do
it every PROJINT seconds. */
if (fdate || !istimer || ((cctime - lctime) > PROJINT)) {
projillum(wtab, xdots, ydots, sundec);
wtabs = wtab;
wtab = wtab1;
wtab1 = wtabs;
lctime = cctime;
}
sunlong = fixangle(180.0 + (sunra - (gt * 15)));
xl = sunlong * (xdots / 360.0);
/* If the subsolar point has moved at least one pixel, update
the illuminated area on the screen. */
if (fdate || !istimer || (onoon != xl)) {
if (bufferio)
pw_batch_on(0);
moveterm(wtab1, xl, wtab, onoon, xdots, ydots);
if (bufferio)
pw_batch_off(0);
onoon = xl;
}
/* Display time */
sprintf(tbuf, "\033p\033Y%c%c%02d:%02d:%02d %s %02d/%02d/%02d",
' '+22, ' '+7,
lt.tm_hour, lt.tm_min, 2*lt.tm_sec,
wdname[lt.tm_wday],
lt.tm_mon + 1, lt.tm_mday, (lt.tm_year % 100));
puts(tbuf);
/* Display mode */
sprintf(tbuf, "\033p\033Y%c%c(", ' '+23, ' '+7);
strcat(tbuf, (animate) ? "Animate" : "Real time" );
if (animate) {
strcat(tbuf, (idir < 0) ? ", <<" : ", >>");
switch (abs(lincr)) {
case 3600L:
strcat(tbuf, " hour");
break;
case 86400L:
strcat(tbuf, " day");
break;
case 604800L:
strcat(tbuf, " week");
break;
case 2592000L:
strcat(tbuf, " month");
break;
case 31536000L:
strcat(tbuf, " year");
break;
}
}
strcat(tbuf, ")");
puts(tbuf);
/* Display credits */
printf("\033p\033Y%c%cSUN : John Walker, Autodesk, Inc.", ' '+22, ' '+40);
printf("\033p\033Y%c%cATARI : Joep Mathijssen", ' '+23, ' '+40);
}
/* Frame event processor
static frame_event_proc(frame, event, arg, type)
Frame frame;
Event *event;
Notify_arg arg;
Notify_event_type type;
{
switch (event_id(event)) {
case WIN_REPAINT:
if (window_get(bf, FR